<template>
  <div class="menu">
    <el-button type="primary" :icon="useRenderIcon(plus)" @click="topAdd"
      >新增</el-button
    >
    <div class="my-table mt-4">
      <el-table
        :data="tableData"
        style="width: 100%"
        row-key="menuId"
        border
        default-expand-all
        v-loading="isMenuLoading"
      >
        <el-table-column
          prop="name"
          label="菜单名称"
          min-width="200px"
          align="center"
        />
        <el-table-column prop="icon" label="图标" align="center">
          <template v-slot="scope">
            <div class="flex justify-center">
              <IconifyIconOnline :icon="scope.row.icon" />
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="sort" label="排序" align="center">
          <template v-slot="scope">
            <el-tag>{{ scope.row.sort }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="hidden" label="是否隐藏" align="center">
          <template v-slot="scope">
            <el-tag>{{ scope.row.isHidden ? "是" : "否" }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column
          prop="path"
          label="连接地址"
          min-width="200px"
          align="center"
        />
        <el-table-column
          prop="template"
          label="组件路径"
          min-width="200px"
          align="center"
        />
        <el-table-column label="操作" min-width="200px">
          <template v-slot="scope">
            <el-button
              type="primary"
              :icon="useRenderIcon(plus)"
              size="small"
              @click="add(scope.row.menuId)"
            />
            <el-button
              type="primary"
              size="small"
              :icon="useRenderIcon(edit)"
              @click="editItem(scope.row)"
            />
            <el-button
              type="primary"
              :icon="useRenderIcon(iconDel)"
              size="small"
              @click="del(scope.row.menuId)"
            />
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- 添加编辑弹窗 -->
    <el-dialog
      v-model="dialogVisible"
      :title="isEdit ? '编辑菜单' : '添加菜单'"
      width="50%"
      @closed="closed"
    >
      <div class="dialog-content">
        <el-form
          ref="ruleFormRef"
          :model="menuForm"
          :rules="rules"
          label-width="80px"
          class="demo-ruleForm"
          status-icon
        >
          <el-form-item label="菜单图标" prop="icon" v-if="isTop">
            <el-input v-model="menuForm.icon" />
          </el-form-item>
          <el-form-item label="菜单名称" prop="name">
            <el-input v-model="menuForm.name" />
          </el-form-item>
          <el-form-item label="菜单排序" prop="sort">
            <el-input-number
              v-model="menuForm.sort"
              :min="0"
              controls-position="right"
              size="large"
            />
          </el-form-item>
          <el-form-item label="连接地址" prop="path">
            <el-input v-model.trim="menuForm.path" />
          </el-form-item>
          <el-form-item label="组件路径" prop="template">
            <el-input v-model.trim="menuForm.template" />
          </el-form-item>
          <el-form-item label="是否隐藏" prop="hidden">
            <el-radio-group v-model="menuForm.hidden">
              <el-radio :label="true" size="large">是</el-radio>
              <el-radio :label="false" size="large">否</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submit" :loading="isLoading">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import plus from "@iconify-icons/ep/plus";
import iconDel from "@iconify-icons/ep/delete";
import edit from "@iconify-icons/ep/edit";
import { ref, onMounted, reactive } from "vue";
import { MenuResponseTree, MenuAddRequest } from "@/api/menu/menu";
import {
  getAllMenu,
  addMenuItem,
  editMenuItem,
  removeMenuItem
} from "@/api/menu/index";
import { convertToNestedArray } from "@/utils/setRoute";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage, ElMessageBox } from "element-plus";
defineOptions({
  name: "menus"
});
onMounted(() => {
  getALlMenuList();
});
const tableData = ref<MenuResponseTree[]>();
// 获取所有菜单
const isMenuLoading = ref(false);
const getALlMenuList = async () => {
  isMenuLoading.value = true;
  const res = await getAllMenu();
  if (res.code === 0) {
    const sortMenu = res.data.sort((a, b) => b.sort - a.sort);
    tableData.value = convertToNestedArray(sortMenu);
    isMenuLoading.value = false;
  }
};
// 添加编辑
const dialogVisible = ref(false);
const isTop = ref(true);
const isEdit = ref(false);
const ruleFormRef = ref<FormInstance>();
const menuForm = ref<MenuAddRequest>({
  name: "",
  path: "",
  sort: 0,
  hidden: true,
  parentId: "",
  icon: "",
  template: ""
});
const rules = reactive<FormRules<MenuAddRequest>>({
  icon: [{ required: true, message: "请输入图标", trigger: "blur" }],
  name: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
  sort: [{ required: true, message: "请选择菜单排序", trigger: "blur" }]
});
// 顶层新增
const topAdd = () => {
  isTop.value = true;
  isEdit.value = false;
  dialogVisible.value = true;
};
const add = (id: string) => {
  isTop.value = false;
  isEdit.value = false;
  menuForm.value.parentId = id;
  dialogVisible.value = true;
};
// 提交
const addSubmit = async () => {
  const res = await addMenuItem(menuForm.value);
  if (res.code === 0) {
    ElMessage.success("添加成功");
  }
};
// 编辑
const menuId = ref("");
const editItem = (item: MenuResponseTree) => {
  isEdit.value = true;
  menuId.value = item.menuId;
  for (const key in menuForm.value) {
    menuForm.value[key] = item[key];
  }
  isTop.value = item.parentId ? false : true;
  dialogVisible.value = true;
};
const editSubmit = async () => {
  const menu = { ...menuForm.value, menuId: menuId.value };
  const res = await editMenuItem(menu);
  if (res.code === 0) {
    ElMessage.success("修改成功");
  }
};
const isLoading = ref(false);
const submit = () => {
  ruleFormRef.value.validate(async valid => {
    if (valid) {
      isLoading.value = true;
      if (isEdit.value) {
        await editSubmit();
      } else {
        await addSubmit();
      }
      isLoading.value = false;
      getALlMenuList();
    }
  });
};
const closed = () => {
  menuForm.value = {
    name: "",
    path: "",
    sort: 0,
    hidden: true,
    parentId: "",
    icon: "",
    template: ""
  };
  ruleFormRef.value.clearValidate();
};
// 移除
const del = (menuId: string) => {
  ElMessageBox.confirm("您确定要删除吗?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  })
    .then(async () => {
      const res = await removeMenuItem(menuId);
      if (res.code === 0) {
        ElMessage({
          type: "success",
          message: "删除成功"
        });
        getALlMenuList();
      }
    })
    .catch(() => {
      ElMessage({
        type: "info",
        message: "已取消"
      });
    });
};
</script>
